/*******************************************************************************
GSound.cpp

	Author:		LiuDingXi
	e-mail:		liudx@gmail.com
	Date time:	2009-08-26

	Copyright (C) 2009
	All rights reserved.
	
*******************************************************************************/
#include "StdAfx.h"
#include "GSound.h"

#if (_OS_ == _OS_WINNT_)
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#endif//(_OS_ == _OS_WINNT_)

////////////////////////////////////////////////////////////////////////////////

GSound::GSound()
{
	memset(m_szFolder, 0, sizeof(m_szFolder));

#if (_OS_ == _OS_WINNT_)
	m_MusicID = 0;
	m_SoundID = 0;
#endif //(_OS_ == _OS_WINNT_)

#if (_OS_ == _OS_IPHONE_)
	m_MusicID = 0;
	m_SoundID = 0;
#endif //(_OS_ == _OS_IPHONE_)


#if (_OS_ == _OS_SYMBIAN_)
	m_pSound = NULL;
	m_pMusic = NULL;
#endif/(_OS_ == _OS_SYMBIAN_)
}

GSound::~GSound()
{
	Uninitialize();
}


BOOL GSound::Uninitialize()
{
	SoundFree();
	MusicFree();
	return TRUE;
}

#if (_OS_ == _OS_WINNT_)
#include <mmsystem.h>
#include <digitalv.h>
#pragma comment(lib, "winmm.lib")

BOOL GSound::Initialize(LPCTSTR szFolder)
{
	_tcscpy(m_szFolder, szFolder);
	return TRUE;
}

BOOL GSound::SoundLoad(LPCTSTR szSoundFile)
{
	SoundFree();

	if(m_szFolder != NULL)
	{
		TCHAR szFilePath[MAX_PATH];
		_tcscpy(szFilePath, m_szFolder);
		_tcscat(szFilePath, szSoundFile);

		MCI_OPEN_PARMS pm;
		pm.dwCallback = NULL;
		pm.lpstrAlias = NULL;
		pm.lpstrDeviceType = _T("sequencer");
		pm.lpstrElementName = szFilePath;
		pm.wDeviceID = NULL;

		if(0 == mciSendCommand(NULL,MCI_OPEN, MCI_OPEN_ELEMENT, (DWORD)&pm))
		{
			m_SoundID = pm.wDeviceID;
			return TRUE;
		}
	}
	return FALSE;
}

BOOL GSound::SoundFree()
{
	if(m_SoundID)
	{
		MCI_GENERIC_PARMS gp;
		memset(&gp, 0, sizeof(gp));

		mciSendCommand(m_SoundID, MCI_CLOSE, MCI_WAIT, (DWORD)&gp);

		m_SoundID = 0;
		return TRUE;
	}
	return FALSE;
}

BOOL GSound::SoundPlay()
{
	if(m_SoundID != 0)
	{
		MCI_PLAY_PARMS pm;
		memset(&pm, 0, sizeof(pm));

		DWORD dwParam = MCI_FROM;

		mciSendCommand(m_SoundID, MCI_PLAY, dwParam, (DWORD)&pm);
		return TRUE;
	}
	return FALSE;
}

VOLM GSound::SoundGetVolume()
{
	HMIXER	hMixer;
	mixerOpen(&hMixer, 0, 0, 0, 0);

    MIXERLINE mxl; 
    mxl.cbStruct = sizeof(mxl); 
    mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT; 
    mixerGetLineInfo((HMIXEROBJ)hMixer,&mxl,MIXER_GETLINEINFOF_COMPONENTTYPE);

	MIXERCONTROL mixerCtrl;
    MIXERLINECONTROLS mxlc; 
    mxlc.cbStruct = sizeof(mxlc); 
    mxlc.dwLineID = mxl.dwLineID; 
    mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; 
    mxlc.cControls = 1; 
    mxlc.cbmxctrl = sizeof(MIXERCONTROL); 
    mxlc.pamxctrl = &mixerCtrl; 
    mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc,MIXER_GETLINECONTROLSF_ONEBYTYPE);


    MIXERCONTROLDETAILS   mxcd;
    MIXERCONTROLDETAILS_UNSIGNED   vol;
	vol.dwValue=0; 
    mxcd.hwndOwner = 0; 
    mxcd.cbStruct = sizeof(mxcd); 
    mxcd.dwControlID = mixerCtrl.dwControlID; 
    mxcd.cbDetails = sizeof(vol); 
    mxcd.paDetails = &vol; 
    mxcd.cChannels = 1; 
    mixerGetControlDetails((HMIXEROBJ)hMixer,&mxcd,MIXER_OBJECTF_HMIXER|MIXER_GETCONTROLDETAILSF_VALUE);
    
	mixerClose(hMixer);

    return   vol.dwValue; 
}

BOOL GSound::SoundSetVolume(VOLM Volume)
{
	HMIXER		hMixer;

	mixerOpen(&hMixer, 0, 0, 0, 0);

    MIXERLINE mxl; 
    mxl.cbStruct = sizeof(mxl); 
    mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT; 
    mixerGetLineInfo((HMIXEROBJ)hMixer,&mxl,MIXER_GETLINEINFOF_COMPONENTTYPE);

	MIXERCONTROL mixerCtrl;
    MIXERLINECONTROLS mxlc; 
    mxlc.cbStruct = sizeof(mxlc); 
    mxlc.dwLineID = mxl.dwLineID; 
    mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; 
    mxlc.cControls = 1; 
    mxlc.cbmxctrl = sizeof(MIXERCONTROL); 
    mxlc.pamxctrl = &mixerCtrl; 
    mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc,MIXER_GETLINECONTROLSF_ONEBYTYPE);

    MIXERCONTROLDETAILS   mxcd;
    MIXERCONTROLDETAILS_UNSIGNED vol;
    vol.dwValue = Volume;
    mxcd.hwndOwner = 0;
    mxcd.dwControlID = mixerCtrl.dwControlID;
    mxcd.cbStruct = sizeof(mxcd);
    mxcd.cbDetails = sizeof(vol);
    mxcd.paDetails = &vol;
    mxcd.cChannels = 1;
    if(mixerSetControlDetails((HMIXEROBJ)hMixer,&mxcd,
        MIXER_OBJECTF_HMIXER|MIXER_SETCONTROLDETAILSF_VALUE)) 
        return FALSE;

    return TRUE; 
}


BOOL GSound::MusicLoad(LPCTSTR szFileName)
{
	MusicFree();
	
	if(m_szFolder != NULL)
	{
		TCHAR szFilePath[MAX_PATH];
		_tcscpy(szFilePath, m_szFolder);
		_tcscat(szFilePath, szFileName);

		MCI_OPEN_PARMS pm;
		pm.dwCallback = NULL;
		pm.lpstrAlias = NULL;
		pm.lpstrDeviceType = _T("MPEGAudio");
		pm.lpstrElementName = szFilePath;
		pm.wDeviceID = NULL;

		if(0 == mciSendCommand(NULL,MCI_OPEN, MCI_OPEN_ELEMENT, (DWORD)&pm))
		{
			m_MusicID = pm.wDeviceID;
			return TRUE;
		}
	}
	return FALSE;
}

BOOL GSound::MusicFree()
{
	if(m_MusicID)
	{
		MCI_GENERIC_PARMS gp;
		memset(&gp, 0, sizeof(gp));

		mciSendCommand(m_MusicID, MCI_STOP, MCI_WAIT, (DWORD)&gp);

		m_MusicID = 0;
		return TRUE;
	}
	return FALSE;
}

BOOL GSound::MusicPlay(BOOL bLoop)
{
	if(m_MusicID != 0)
	{
		MCI_PLAY_PARMS pm;
		memset(&pm, 0, sizeof(pm));

		DWORD dwParam = MCI_FROM;
		if(bLoop)
			dwParam |= MCI_DGV_PLAY_REPEAT;

		mciSendCommand(m_MusicID, MCI_PLAY, dwParam, (DWORD)&pm);
		return TRUE;
	}
	return FALSE;
}

BOOL GSound::MusicPause()
{
	if(m_MusicID)
	{
		MCI_GENERIC_PARMS gp;
		memset(&gp, 0, sizeof(gp));

		mciSendCommand(m_MusicID, MCI_PAUSE, MCI_WAIT, (DWORD)&gp);
		return TRUE;
	}
	return FALSE;
}

BOOL GSound::MusicResume()
{
	if(m_MusicID)
	{
		MCI_GENERIC_PARMS gp;
		memset(&gp, 0, sizeof(gp));

		mciSendCommand(m_MusicID, MCI_RESUME, MCI_WAIT, (DWORD)&gp);
		return TRUE;
	}
	return FALSE;
}

BOOL GSound::MusicStop()
{
	if(m_MusicID)
	{
		MCI_GENERIC_PARMS gp;
		memset(&gp, 0, sizeof(gp));

		mciSendCommand(m_MusicID, MCI_STOP, MCI_WAIT, (DWORD)&gp);
		return TRUE;
	}
	return FALSE;
}


VOLM GSound::MusicGetVolume()
{
	HMIXER	hMixer;
	mixerOpen(&hMixer, 0, 0, 0, 0);

    MIXERLINE mxl; 
    mxl.cbStruct = sizeof(mxl); 
    mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; 
    mixerGetLineInfo((HMIXEROBJ)hMixer,&mxl,MIXER_GETLINEINFOF_COMPONENTTYPE);

	MIXERCONTROL mixerCtrl;
    MIXERLINECONTROLS mxlc; 
    mxlc.cbStruct = sizeof(mxlc); 
    mxlc.dwLineID = mxl.dwLineID; 
    mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; 
    mxlc.cControls = 1; 
    mxlc.cbmxctrl = sizeof(MIXERCONTROL); 
    mxlc.pamxctrl = &mixerCtrl; 
    mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc,MIXER_GETLINECONTROLSF_ONEBYTYPE);


    MIXERCONTROLDETAILS   mxcd;
    MIXERCONTROLDETAILS_UNSIGNED   vol;
	vol.dwValue=0; 
    mxcd.hwndOwner = 0; 
    mxcd.cbStruct = sizeof(mxcd); 
    mxcd.dwControlID = mixerCtrl.dwControlID; 
    mxcd.cbDetails = sizeof(vol); 
    mxcd.paDetails = &vol; 
    mxcd.cChannels = 1; 
    mixerGetControlDetails((HMIXEROBJ)hMixer,&mxcd,MIXER_OBJECTF_HMIXER|MIXER_GETCONTROLDETAILSF_VALUE);
    
	mixerClose(hMixer);

    return   vol.dwValue; 
}

BOOL GSound::MusicSetVolume(VOLM Volume)
{
	HMIXER		hMixer;

	mixerOpen(&hMixer, 0, 0, 0, 0);

    MIXERLINE mxl; 
    mxl.cbStruct = sizeof(mxl); 
    mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; 
    mixerGetLineInfo((HMIXEROBJ)hMixer,&mxl,MIXER_GETLINEINFOF_COMPONENTTYPE);

	MIXERCONTROL mixerCtrl;
    MIXERLINECONTROLS mxlc; 
    mxlc.cbStruct = sizeof(mxlc); 
    mxlc.dwLineID = mxl.dwLineID; 
    mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; 
    mxlc.cControls = 1; 
    mxlc.cbmxctrl = sizeof(MIXERCONTROL); 
    mxlc.pamxctrl = &mixerCtrl; 
    mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc,MIXER_GETLINECONTROLSF_ONEBYTYPE);

    MIXERCONTROLDETAILS   mxcd;
    MIXERCONTROLDETAILS_UNSIGNED vol;
    vol.dwValue = Volume;
    mxcd.hwndOwner = 0;
    mxcd.dwControlID = mixerCtrl.dwControlID;
    mxcd.cbStruct = sizeof(mxcd);
    mxcd.cbDetails = sizeof(vol);
    mxcd.paDetails = &vol;
    mxcd.cChannels = 1;
    if(mixerSetControlDetails((HMIXEROBJ)hMixer,&mxcd,
        MIXER_OBJECTF_HMIXER|MIXER_SETCONTROLDETAILSF_VALUE)) 
        return FALSE;

    return TRUE; 
}

#endif


#if (_OS_ == _OS_IPHONE_)
#include "iPhone_Sound.h"


void InterruptionListener(void *inUserData, UInt32 interruptionState)
{
	if (interruptionState == kAudioSessionBeginInterruption)	
	{
		// deactivate our audio session
		
		AudioSessionSetActive( FALSE );
		
		SoundEngine_PauseBackgroundMusic();

		SoundEngine_TeardownForSound();      
	}
	else if (interruptionState == kAudioSessionEndInterruption)
	{
		// activate our audio session
		AudioSessionSetActive( TRUE );
		
		//SoundEngine_Initialize(44100);
		SoundEngine_InitializeForSound(0);
		SoundEngine_SetListenerPosition(0.0, 0.0, 1.0);
		
		SoundEngine_SetEffectsVolume(0.5f);
		SoundEngine_SetBackgroundMusicVolume(0.5f);
		
		SoundEngine_ResumeBackgroundMusic();
	} 
}

BOOL GSound::Initialize(LPCTSTR szFolder)
{
	_tcscpy(m_szFolder, szFolder);

	AudioSessionInitialize(NULL, NULL, InterruptionListener, NULL);
	//run at 44Khz.
	CALL_SOUNDENGINE_FUNCTION(SoundEngine_Initialize, 0 );//24000);
	CALL_SOUNDENGINE_FUNCTION(SoundEngine_SetListenerPosition, 0.0, 0.0, 1);
	
	m_Volume = 0.5f;
	SoundEngine_SetEffectsVolume(m_Volume);
	SoundEngine_SetBackgroundMusicVolume(m_Volume);

	return TRUE;
}

BOOL GSound::SoundLoad(LPCTSTR szSoundFile)
{
	SoundFree();

	if(m_szFolder != NULL)
	{
		TCHAR szFilePath[MAX_PATH];
		_tcscpy(szFilePath, m_szFolder);
		_tcscat(szFilePath, szSoundFile);

		SoundEngine_LoadEffect(szFilePath, &m_SoundID);
		return TRUE;
	}
	return FALSE;
}

BOOL GSound::SoundFree()
{
	if(m_SoundID)
	{
		SoundEngine_UnloadEffect(m_SoundID);
		m_SoundID = 0;
		return TRUE;
	}
	return FALSE;
}

BOOL GSound::SoundPlay()
{
	if(m_SoundID)
	{
		SoundEngine_StartEffect(m_SoundID);
		return TRUE;
	}
	return FALSE;
}

VOLM GSound::SoundGetVolume()
{
	return m_Volume;
}

BOOL GSound::SoundSetVolume(VOLM Volume)
{
	SoundEngine_SetEffectsVolume(Volume);
	m_Volume = Volume;
    return TRUE; 
}

BOOL GSound::MusicLoad(LPCTSTR szFileName)
{
	MusicFree();
	
	if(m_szFolder != NULL)
	{
		TCHAR szFilePath[MAX_PATH];
		_tcscpy(szFilePath, m_szFolder);
		_tcscat(szFilePath, szFileName);

		SoundEngine_LoadBackgroundMusicTrack(szFilePath, FALSE, FALSE);

		m_MusicID = 1;
		return TRUE;
	}
	return FALSE;
}

BOOL GSound::MusicFree()
{
	if(m_MusicID)
	{
		SoundEngine_UnloadBackgroundMusicTrack();
		m_MusicID = 0;
		return TRUE;
	}
	return FALSE;
}

BOOL GSound::MusicPlay(BOOL bLoop)
{
	if(m_MusicID)
	{
		SoundEngine_StartBackgroundMusic();
		if(!bLoop)
		{
			SoundEngine_StopBackgroundMusic(TRUE);
		}
		return TRUE;
	}
	return FALSE;
}

BOOL GSound::MusicPause()
{
	if(m_MusicID)
	{
		SoundEngine_PauseBackgroundMusic();
		return TRUE;
	}
	return FALSE;
}

BOOL GSound::MusicResume()
{
	if(m_MusicID)
	{
		SoundEngine_ResumeBackgroundMusic();
		return TRUE;
	}
	return FALSE;
}

BOOL GSound::MusicStop()
{
	if(m_MusicID)
	{
		SoundEngine_StopBackgroundMusic(FALSE);
		return TRUE;
	}
	return FALSE;
}


VOLM GSound::MusicGetVolume()
{
	return SoundEngine_GetBackgroundMusicVolume();
}

BOOL GSound::MusicSetVolume(VOLM Volume)
{
	SoundEngine_SetBackgroundMusicVolume(Volume);
    return TRUE; 
}

#endif


#if (_OS_ == _OS_SYMBIAN_)
#include "S60_Sound.h"

BOOL GSound::Initialize(LPCTSTR szFolder)
{
	_tcscpy(m_szFolder, szFolder);
	return TRUE;
}

BOOL GSound::SoundLoad(LPCTSTR szSoundFile)
{
	SoundFree();

	if(m_szFolder != NULL)
	{
		TCHAR szFilePath[MAX_PATH];
		_tcscpy(szFilePath, m_szFolder);
		_tcscat(szFilePath, szSoundFile);

		if(m_pSound == NULL)
		{
			TPtrC16 des;
			des.Set( (const TUint16*)szFilePath , _tcslen(szFilePath) );

			m_pSound = new CSoundPlayer::NewL(szFilePath);

			return (m_pSound != NULL ? TRUE : FALSE);
		}

	}
	return FALSE;
}

BOOL GSound::SoundFree()
{
	if(m_pSound)
	{
		delete m_pSound;
		m_pSound = NULL;
		return TRUE;
	}
	return FALSE;
}

BOOL GSound::SoundPlay()
{
	if(m_pSound)
	{
		m_pSound->Play();
		return TRUE;
	}
	return FALSE;
}

BOOL GSound::MusicLoad(LPCTSTR szFileName)
{
	MusicFree();
	
	if(m_szFolder != NULL)
	{
		TCHAR szFilePath[MAX_PATH];
		_tcscpy(szFilePath, m_szFolder);
		_tcscat(szFilePath, szFileName);

		if(m_pMusic == NULL)
		{
			TPtrC16 des;
			des.Set( (const TUint16*)szFilePath , _tcslen(szFilePath) );

			m_pMusic = new CSoundPlayer::NewL(szFilePath);

			return (m_pMusic != NULL ? TRUE : FALSE);
		}

	}
	return FALSE;
}

BOOL GSound::MusicFree()
{
	if(m_pMusic)
	{
		delete m_pMusic;
		m_pMusic = NULL;
		return TRUE;
	}
	return FALSE;
}

BOOL GSound::MusicPlay(BOOL bLoop)
{
	if(m_pMusic)
	{
		m_pMusic->Play(bLoop);
		return TRUE;
	}
	return FALSE;
}

BOOL GSound::MusicPause()
{
	if(m_pMusic)
	{
		m_pMusic->Stop();
		return TRUE;
	}
	return FALSE;
}

BOOL GSound::MusicResume()
{
	if(m_pMusic)
	{
		return TRUE;
	}
	return FALSE;
}

BOOL GSound::MusicStop()
{
	if(m_pMusic)
	{
		m_pMusic->Stop();
		return TRUE;
	}
	return FALSE;
}

#endif

